Перейти к основному содержимому

9.05. Блоки

Родителям и детям
Что такое блок кода
{Блок}
блок
и графический блок
Blockly / ScratchJr — визуальные блоки как «конструктор»
Добавить mermaid схему
Добавить задачи

Представьте, что вы хотите построить дом. Вы не начинаете с того, чтобы сразу вбить гвоздь в облако — сначала берёте кирпичи. Один кирпич — это просто кусок глины. Но когда вы складываете кирпичи в определённом порядке, между ними появляются стены, окна, крыша… и вот уже стоит дом, в котором можно жить.

Программы устроены точно так же. Их строят не из кирпичей, а из блоков — особых частей кода, которые группируют действия, условия или данные. Блоки помогают программисту не запутаться: они показывают, что к чему относится, когда что выполняется и как части программы связаны между собой.

Эта глава — про то, что такое блок, зачем он нужен, и как с ним работать. Мы поговорим и про текстовые блоки (как в настоящих языках программирования), и про графические — те, что вы могли видеть в Scratch или Blockly. И самое главное: вы поймёте, что блочный подход — это не «упрощение», а мощный способ мышления, которым пользуются даже самые опытные разработчики.


Что такое блок кода? И почему он похож на скобки

В большинстве языков программирования — например, в C#, Java, JavaScript, C++ — блок кода обозначается фигурными скобками:

{
// здесь находится блок
}

⚠ Обратите внимание: в тексте выше мы написали {Блок}, но технически это не совсем корректно — просто {Блок} — это обозначение, а не настоящий код. Настоящий блок всегда содержит содержимое между открывающей { и закрывающей } скобкой.

Фигурные скобки — это как двери в комнату: всё, что находится внутри этих дверей, принадлежит одному и тому же смысловому «помещению». Например:

if (свет горит) {
выключить_свет();
сказать("Теперь темно!");
}

Здесь весь код между { и } — это блок, который выполняется только если условие свет горит истинно. Если бы не было скобок, компьютер не знал бы, какие команды относятся к условию if, а какие — нет.

📌 Важно: блок — это не просто «кусок кода». Это логическая единица, внутри которой:

  • работают одни и те же правила (например, видимость переменных),
  • все команды выполняются последовательно (если не указано иное),
  • можно легко добавить или убрать целую группу действий, не нарушая остальную программу.

Представьте, что вы пишете инструкцию для робота:

  1. Возьми яблоко.
  2. Помой его.
  3. Положи на тарелку.
  4. Скажи: «Готово!»

А теперь — добавим условие:

Если на кухне есть яблоко,
то

  1. Возьми яблоко.
  2. Помой его.
  3. Положи на тарелку.
  4. Скажи: «Готово!»
    Иначе
    скажи: «Яблока нет 😢».

Здесь два блока: один — после слова «то», другой — после «иначе». В текстовом коде это выглядело бы так (на условном псевдокоде):

если (на_кухне_есть_яблоко) {
взять_яблоко();
помыть();
положить_на_тарелку();
сказать("Готово!");
} иначе {
сказать("Яблока нет 😢");
}

Обратите внимание: отступы (пробелы в начале строк) и скобки работают вместе — они помогают и человеку, и компьютеру видеть границы блоков. Отступы — для нас, скобки — для машины.


А если не печатать? Графические блоки — конструктор программ

Для детей (и не только!) существует другой подход: вместо печати кода — перетаскивание блоков. Такие среды, как Scratch, Blockly (от Google) или EduBlocks, превращают программирование в сборку конструктора — как LEGO.

Вот как это устроено.

Каждая команда — это отдельный «кирпичик» с определённой формой:

  • Блоки-«шляпки» (например, «когда зелёный флаг нажат») — всегда в начале.
  • Блоки-«команды» (например, «двигаться на 10 шагов») — можно присоединять друг к другу.
  • Блоки-«условия» (например, «если … то …») — имеют выемку, куда вставляется условие, и «карман» — куда можно вложить другие блоки.

Визуально это выглядит примерно так (в текстовом приближении):

┌──────────────────────┐
│ если <кошка касается мыши> то │
├──────────────────────┤
│ сказать "Мяу!" 2 сек │
│ изменить размер на 10% │
└──────────────────────┘

А теперь — ключевой момент: графические блоки — это не «игрушка» и не «ненастоящее программирование». Это то же самое, только в другой форме.

Технически Blockly, например, внутри себя хранит древовидную структуру — точно такую же, какую строит компилятор из текстового кода. Когда вы перетаскиваете блок если, программа создаёт узел с типом IfStatement, внутрь которого вкладываются узлы Condition и ThenBlock. Это — абстрактное синтаксическое дерево, или AST (Abstract Syntax Tree).

📌 Простыми словами:

Когда вы собираете блоки в Scratch — вы не просто играете. Вы строите структуру программы, учитесь правильной вложенности, понимаете, что «то» и «иначе» — это отдельные «комнаты», и что нельзя положить действие вне блока условия, если оно должно выполняться только при выполнении условия.

Это особенно важно для детей 8–12 лет: печатать на клавиатуре им трудно — руки ещё не привыкли, ошибки в раскладке или пунктуации вызывают раздражение. Но логика — она уже есть. Графические блоки освобождают мышление от механики ввода и позволяют сосредоточиться на главном: на последовательности, условиях и циклах.


Как устроена вложенность: от «если» к действиям

Рассмотрим типичную структуру с вложенными блоками.

В текстовом виде (на Python-подобном псевдокоде):

если (идёт_дождь) {
взять("зонтик");
если (ветер_сильный) {
держать_зонтик_крепко();
}
идти_в_школу();
}

Здесь у нас:

  • Внешний блок — всё, что связано с дождём.
  • Внутри него — ещё один блок, относящийся только к случаю сильного ветра.

То есть:
🔹 «идти_в_школу» выполняется всегда, если идёт дождь.
🔹 «держать_зонтик_крепко» — только если идёт дождь и дует сильный ветер.

Это — иерархия блоков, и она критически важна. Ошибка в расстановке скобок или неправильная вложенность блоков в Scratch (например, вытащить один блок из-под «если») — приведёт к тому, что программа будет вести себя не так, как ожидается.

Чтобы лучше это представить, воспользуемся схемой.


Схема: Структура блоков как дерево

Ниже — диаграмма в формате Mermaid, которую можно вставить в любой современный редактор (включая Obsidian, Typora, или онлайн-редактор Mermaid Live Editor).

💡 Как читать:

  • Круглые узлы — это блоки условий (если).
  • Зелёные прямоугольники — это действия, выполняемые внутри блоков.
  • Стрелки показывают, когда какое действие происходит.

Обратите внимание: блок идти_в_школу() находится после вложенного ветер_сильный, но всё ещё внутри внешнего если идёт_дождь. Это значит — он зависит от дождя, но не зависит от ветра.


Почему блоки — это фундамент, а не деталь

Многие думают: «Блоки — это просто скобки, их легко запомнить». Но это не так.

Блоки учат нас структурировать мышление. Без понимания блоков невозможно:

  • писать условия правильно (иначе действия выполнятся всегда, даже когда не должны),
  • использовать циклы (например, «повторять 5 раз {…}» — что внутри {…}? Только то, что вы вложили!),
  • работать с функциями (всё, что функция «делает» — находится в её блоке),
  • избегать багов при копировании кода (если вы скопируете только часть блока — программа сломается).

Даже в языках без фигурных скобок (например, Python, где блоки обозначаются отступами), идея остаётся той же:

if идёт_дождь:
взять("зонтик")
if ветер_сильный:
держать_зонтик_крепко()
идти_в_школу() # ← этот отступ говорит: «я всё ещё в блоке if идёт_дождь»

Здесь отступ в 4 пробела — это и есть «невидимая скобка». И если вы случайно уберёте пробелы перед идти_в_школу(), эта команда окажется вне условия — и будет выполняться всегда, даже в солнечный день.

Так что блоки — это не синтаксис. Это границы ответственности: что за что отвечает, и когда это происходит.


Практика: задачи для закрепления

Теперь — ваша очередь. Вот несколько заданий разного уровня сложности. Выполнять можно в тетради, в Scratch, в Blockly — или просто нарисовать схему.

🔹 Задача 1. «Правильные скобки» (уровень: 8–10 лет)

Вот «испорченный» код с пропущенными или лишними скобками. Найдите ошибки и исправьте:

если (я_голоден) {
съесть("яблоко")
если (яблоко_кислое) {
сказать("Фу!")
// ← здесь что-то не так?
сказать("Спасибо за еду!")

Подсказка: посчитайте { и }. Должно быть поровну. И подумайте: команда сказать("Спасибо…") — она должна выполняться всегда, или только когда я голоден?

🔹 Задача 2. «Сборка блоков» (уровень: 9–12 лет)

У вас есть такие блоки в Scratch/Blockly:

  • когда зелёный флаг нажат
  • если <x > 0> то
  • сказать "Вправо!"
  • повторить 3 раза
  • изменить x на 10
  • конец (в Blockly такого блока нет — он не нужен!)

Соберите программу, которая:

  1. При запуске проверяет: если персонаж находится правее центра (x > 0),
  2. То 3 раза двигает его ещё правее и говорит «Вправо!» после каждого шага.

Нарисуйте, как должны быть вложены блоки. Где находится повторить? Внутри если или снаружи?

🔹 Задача 3. «Дерево решений» (уровень: 12–16 лет)

Напишите псевдокод (на русском, со скобками {}) для следующей ситуации:

Робот-помощник должен приготовить бутерброд.
Правила:

  • Если есть хлеб и сыр — сделать сырный бутерброд.
  • Если есть хлеб и колбаса, но нет сыра — сделать мясной.
  • Если есть и сыр, и колбаса — сделать «праздничный» (сначала сыр, потом колбаса).
  • Если хлеба нет — пойти в магазин.

Внутри каждого варианта — последовательность действий: взять хлеб, положить ингредиент, накрыть второй ломтиком.

Сколько уровней вложенности у вас получилось? Могут ли блоки если быть внутри других если? Почему да/нет?

🔹 Бонус: «Рефлексия»

Почему, по-вашему, в Blockly нельзя вытащить блок изменить x на 10 изнутри повторить, не разорвав соединение? Что бы случилось с программой, если бы это было можно — как в обычном текстовом редакторе?


Циклы: когда блок нужно выполнить много раз

Мы уже знаем, что блок — это логическая «комната», внутри которой живут команды. А что, если эту комнату нужно пройти не один раз, а десять? Или пока не выполнится какое-то условие?

Для этого существуют циклы — конструкции, которые многократно выполняют один и тот же блок.

Вот три самых распространённых типа:

Тип циклаКогда используетсяПример (на псевдокоде)
повторить N разЗаранее известно, сколько разповторить 5 раз { шаг_вперёд() }
пока (условие)Повторять, пока что-то вернопока (не_у_стены) { шаг_вперёд() }
для каждогоОбработать каждый элемент спискадля каждого фрукта в корзине { съесть(фрукт) }

Важно: все три работают с блоками. То есть, действие, которое повторяется — всегда целиком находится внутри { }.

Вот как это выглядит в текстовом виде (JavaScript-подобно):

// Повторить 4 раза: нарисовать квадрат из 4 шагов
повторить(4) {
вперёд(50);
поворот_направо(90);
}

А в Blockly — это один блок повторить, под который «вставляется» стопка других блоков:

┌──────────────────────┐
│ повторить 4 раза │
├──────────────────────┤
│ вперёд 50 │
│ поворот направо 90 │
└──────────────────────┘

📌 Обратите внимание: если вы не вложите команду внутрь цикла — она выполнится только один раз, после всех повторений.

Например, ошибка новичка:

повторить(3) {
сказать("Привет!");
}
сказать("Пока!"); // ← вне блока — выполнится один раз, после цикла

Если же нужно сказать «Пока!» каждый раз, то и эту команду нужно положить внутрь:

повторить(3) {
сказать("Привет!");
сказать("Пока!"); // ← теперь — трижды
}

Это — ещё один пример того, как блоки защищают от логических ошибок: они заставляют вас явно указать, что относится к повторению, а что — нет.


Функции: блоки, которым дали имя

Представьте, что вы научились складывать бумажный самолётик. Вы делаете это по инструкции:

  1. Согнуть лист пополам.
  2. Завернуть углы к центру.
  3. Согнуть пополам ещё раз.
  4. Отогнуть крылья.

Если друг попросит: «Сделай самолёт!» — вы не будете пересказывать всю инструкцию. Вы просто скажете: «Сейчас сложу самолёт» — и сделаете всё, что уже знаете.

В программировании то же самое делают функции.

Функция — это именованный блок кода, который можно вызывать по имени, сколько угодно раз.

Пример:

функция сложить_самолёт() {
согнуть_пополам();
завернуть_углы();
согнуть_ещё_раз();
отогнуть_крылья();
}

А потом — использовать:

сложить_самолёт();   // один самолёт
сложить_самолёт(); // второй

В Blockly функции тоже есть — они называются «сделать блок» или «определить процедуру». Там вы буквально создаёте свой блок, перетаскивая внутрь другие блоки, а потом этот «суперблок» появляется в палитре и его можно использовать как обычную команду.

📌 Почему это важно для детей?

  • Экономия усилий: не нужно копировать одни и те же действия.
  • Читаемость: вместо 10 строк кода — одна строка включить_режим_ночь().
  • Ошибки легче исправлять: если в самолёте ошибка — её исправляют в одном месте, а не в десяти копиях.
  • Абстракция: появляется возможность думать на уровне целей («взлететь»), а не действий («вперёд, вверх, вперёд…»).

💡 Интересный факт: в Scratch 3.0 есть «Мои блоки» — и дети часто создают функции вроде танцевать_по_кругу, мерцать_цветом, прыгать_три_раза. Это — их первые шаги в инженерном мышлении: не просто делать, а проектировать повторяющиеся решения.


Отладка по блокам: как искать ошибки, не теряя голову

Одна из самых сложных задач в программировании — найти, почему программа работает не так. Особенно когда код длинный.

Здесь блоки снова помогают — потому что их можно проверять по одному.

Представьте: робот не доходит до цели. Вместо того чтобы перечитывать всю программу, вы мысленно «закрываете двери» в одни блоки и смотрите, что происходит внутри других.

Пример:

идти_в_школу() {
если (идёт_дождь) {
взять("зонтик"); // ← работает?
надеть("капюшон"); // ← а это?
}
открыть_дверь(); // ← выполняется?
спуститься_по_лестнице(); // ← и это?
}

Если робот не выходит из дома — возможно, открыть_дверь() находится внутри блока если, хотя должен быть снаружи. Проверяя границы блоков, вы быстро локализуете проблему.

В графических средах отладка ещё проще: Blockly и Scratch позволяют запускать по шагам — и видеть, какой блок сейчас «горит» (выполняется). Это как смотреть, как по конвейеру движутся детали: если где-то застряло — сразу видно.


От графики к тексту: как «перевести» блоки на настоящий язык

Многие думают: «Scratch — это игра, а настоящий код — совсем другой». Но это миф.

Рассмотрим, как один и тот же алгоритм выглядит в трёх форматах:

1. Blockly (визуально)

┌───────────────────────────────┐
│ повторить пока (x < 200) │
├───────────────────────────────┤
│ изменить x на 10 │
│ сказать x │
└───────────────────────────────┘

2. Псевдокод (понятный человеку)

пока (координата x меньше 200) {
увеличить x на 10;
вывести x на экран;
}

3. Настоящий код (JavaScript)

while (x < 200) {
x = x + 10;
console.log(x);
}

Разница — лишь в «обёртке». Смысл одинаковый:

  • условие проверяется перед каждым выполнением блока,
  • содержимое блока — то, что повторяется,
  • границы блока чётко обозначены.

📌 Задание для размышления:
Попробуйте «перевести» следующий Scratch-блок в JavaScript:

┌────────────────────────────────┐
│ если <нажата клавиша [пробел]> то │
├────────────────────────────────┤
│ создать клон [себя] │
│ если <y > 100> то │
│ ├──────────────────────────┤
│ │ сказать "Высоко!" 2 сек │
│ └──────────────────────────┘
└────────────────────────────────┘

Не нужно знать синтаксис точно — попробуйте передать структуру. Где открываются {, где закрываются? Какие блоки вложены?


Практика: продвинутые задачи

🔹 Задача 4. «Цикл внутри условия» (10–13 лет)

Робот находится в коридоре с лампочками. Ему нужно:

  • Идти вперёд, пока не упрётся в стену.
  • Каждый раз, когда он проходит лампочку (координата x кратна 50), — включать её.

Напишите псевдокод с блоками. Учтите:

  • Проверка «кратно 50» — это x % 50 == 0.
  • Движение — шаг_вперёд() (увеличивает x на 10).
  • Остановка — когда у_стены == истина.

Сколько уровней вложенности? Можно ли обойтись без вложенного если?

🔹 Задача 5. «Функция-помощник» (12–15 лет)

Вам нужно нарисовать 3 домика: синий, жёлтый и красный.

Без функций:

// рисуем синий дом
квадрат("синий");
треугольник("синий");

// рисуем жёлтый дом
квадрат("жёлтый");
треугольник("жёлтый");

// и т.д.

Создайте функцию нарисовать_дом(цвет), которая принимает один параметр — название цвета — и рисует дом этого цвета.

Вопросы:

  • Что такое параметр? Почему он нужен?
  • Можно ли вызвать функцию 100 раз с разными цветами? Что изменится в коде?

🔹 Задача 6. «Блоки и реальная жизнь» (для всех возрастов)

Опишите любое своё утреннее действие (например, «собрать рюкзак») как последовательность блоков. Используйте если, повторить, и придумайте хотя бы одну функцию («застегнуть молнию», «положить тетрадь» и т.п.).

Пример начала:

собрать_рюкзак() {
открыть_рюкзак();
повторить для каждого предмета в списке_дел {
если (предмет.нужен_сегодня) {
положить(предмет);
}
}
застегнуть_молнию();
}

Попробуйте найти в своём описании:

  • Вложенные блоки,
  • Повторяющиеся действия,
  • Условия, от которых зависит порядок.

Когда текст встречает графику: «перевод» без потерь

Многие педагоги сталкиваются с проблемой: дети отлично справляются в Scratch, но «теряются» при переходе к Python или JavaScript. Причина не в сложности синтаксиса — а в том, что связь между формами не сделана явной.

Давайте устраним этот разрыв — на конкретном примере.

Возьмём задачу:

«Когда нажимаешь на кота — он мяукает. Если нажать 5 раз — он устаёт и засыпает».

Шаг 1. Blockly / Scratch (визуальная версия)

В Scratch это три блока, соединённых в стек:

┌───────────────────────────────────┐
│ когда щёлкнуть по [кот] │
├───────────────────────────────────┤
│ изменить [счётчик] на 1 │
│ сказать "Мяу!" 1 сек │
│ если <(счётчик) = 5> то │
│ ├────────────────────────────────┤
│ │ переключиться на костюм [спит] │
│ │ остановить [все] │
│ └────────────────────────────────┘
└───────────────────────────────────┘

Обратите внимание на структуру:

  • Есть глобальное действие (увеличить счётчик, сказать «Мяу»),
  • Есть условный блок, вложенный внутрь,
  • Внутри условия — два действия.

Шаг 2. Псевдокод («язык мышления»)

при_щелчке_по_коту() {
счётчик = счётчик + 1;
сказать("Мяу!");

если (счётчик == 5) {
сменить_костюм("спит");
остановить_всё();
}
}

Здесь:

  • при_щелчке_по_коту() — это функция-обработчик события (о событиях — в следующей главе),
  • Все действия, относящиеся к щелчку, — внутри одного блока.

Шаг 3. JavaScript (реальный код в браузере)

let счётчик = 0;

кот.addEventListener("click", function() {
счётчик = счётчик + 1;
кот.сказать("Мяу!");

if (счётчик === 5) {
кот.сменитьКостюм("спит");
кот.остановить();
}
});

Что изменилось?

  • Появились точки (кот.сказать), скобки (function() { … }), ключевые слова (let, if, addEventListener).
  • Но структура блоков осталась неизменной:
    • Весь код обработчика — внутри { } после function,
    • Условие if — со своим блоком внутри.

✅ Вывод:
Переход от Scratch к JavaScript — это не «новый предмет», а замена обёртки при сохранении скелета.
Если ребёнок умеет видеть блоки — синтаксис осваивается как словарь к уже известной грамматике.


Ошибки, которые учат: «лишняя скобка» как учитель

Все делают ошибки. Но в программировании ошибки — не провал, а диалог с машиной. Особенно если понимать, какого рода ошибка произошла.

Разберём три типичные «детские» ошибки с блоками — и чему они учат.

❌ Ошибка 1. «Скобка потерялась»

если (голоден) {
съесть("бутерброд");
// ← забыли }
сказать("Спасибо!");

Что делает компьютер?
Он ищет закрывающую }, и если не находит — выдаёт ошибку:
SyntaxError: Unexpected end of input («Неожиданный конец файла»).

➡️ Урок:
Скобки — как скобки в математике: (2 + 3) — правильно, (2 + 3 — бессмысленно.
Программа должна знать, где кончается условие.

🛠 Совет: используйте редактор с подсветкой парных скобок (например, VS Code). Когда вы ставите курсор на {, он подсвечивает соответствующую }.

❌ Ошибка 2. «Блок выехал наружу»

если (голоден) {
съесть("бутерброд");
}
сказать("Спасибо!"); // ← отступа нет, но в Python это критично!

В Python отступы — часть синтаксиса. Без отступа сказать окажется вне блока if → будет выполняться всегда.

➡️ Урок:
Блоки — это не только { }, но и пространство. Отступ — это «невидимая скобка».

🛠 Совет: настройте редактор на отображение пробелов (в VS Code: View → Render Whitespace). Тогда вы увидите, где заканчивается блок.

❌ Ошибка 3. «Вложил не туда»

В Scratch: перетащили остановить всё снаружи блока если, но хотели — внутрь.

Что происходит?
Кот засыпает после первой тыковки, а не после пятой.

➡️ Урок:
Вложенность — это логическая принадлежность. Действие выполняется тогда и только тогда, когда оно внутри нужного блока.

🛠 Совет: проговаривайте вслух:

«Если счётчик равен 5, тогда — спать. А «Мяу!» — каждый раз, даже если не 5».

Это — вербализация структуры, и она мощнее любого правила.


Блоки в реальном мире: инженерное мышление начинается здесь

Понимание блоков — это не навык программиста. Это — основа инженерного мышления, применимого везде:

СфераАналог блока
КулинарияРецепт: «Если тесто липкое → добавить муку» — это блок условия внутри шага «замесить тесто»
МузыкаТакт — это блок времени; в нём — ноты (действия), разбитые на доли (вложенные блоки)
АрхитектураЭтаж — блок; комната внутри этажа — вложенный блок; шкаф в комнате — ещё глубже
Планирование дня«Утро» → блок; внутри — «зарядка», «завтрак»; в «завтраке» — «если есть йогурт → добавить фрукты»

Когда ребёнок учится выделять блоки, он учится:

  • Декомпозиции — делить сложное на управляемые части,
  • Иерархии — понимать, что главное, а что — деталь,
  • Границам — чётко видеть, где заканчивается зона ответственности одного решения и начинается другого.

Это — то, что делает из «исполнителя» — проектировщика.